package com.woniuxy.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.common.RedisConst;
import com.woniuxy.enumeration.Assert;
import com.woniuxy.enumeration.BusinessCode;
import com.woniuxy.model.dto.UserLoginDto;
import com.woniuxy.model.entity.Customers;
import com.woniuxy.service.CustomersService;
import com.woniuxy.mapper.CustomersMapper;
import com.woniuxy.util.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.Duration;
import java.util.HashMap;
import java.util.Objects;

/**
* @author KOO
* @description 针对表【customers】的数据库操作Service实现
* @createDate 2025-01-04 11:15:16
*/
@Service
@Slf4j
public class CustomersServiceImpl extends ServiceImpl<CustomersMapper, Customers>
    implements CustomersService{
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private JwtUtil jwtUtil;

    @Override
    public String sendSms(String telephone) {
        //随机生成验证码，随机生成4个数字
        String code = RandomStringUtils.randomNumeric(4);
        log.info("短信验证码：{}", code);
        //给手机号发送短信，只需要测试一次，如果成功就没有必要每次发送
//      String result = smsUtil.sendSms(telephone, code);
        String result = "成功";
        Assert.error(!result.equals("成功"), BusinessCode.SMS_SEND_ERROR);
        //验证码放在Redis中，10分钟过期
        redisTemplate.opsForValue().set(RedisConst.SHORT_MESSAGE_SERVICE + ":" + telephone, code, Duration.ofMinutes(10));
        String response = "给手机号：" + telephone.substring(0, 3) + "****" + telephone.substring(7) + "成功发送验证码";
        return response;
    }

    @Override
    public Customers smsLogin(UserLoginDto params, HttpServletRequest request) {
        //获取手机号
        String telephone = params.getTelephone();
        //从Redis中获取验证码
        String smsCode = (String) redisTemplate.opsForValue().get(RedisConst.SHORT_MESSAGE_SERVICE + ":" + telephone);
        //判断验证码是否过期
        Assert.error(Objects.isNull(smsCode), BusinessCode.INVALID_VERIFICATION);
        //判断验证码是否正确
        String code = params.getCode();
        Assert.error(!code.equals(smsCode), BusinessCode.VERIFICATION_ERROR);
        //删除验证码
        redisTemplate.delete(RedisConst.SHORT_MESSAGE_SERVICE + ":" + telephone);
        //根据手机号查询用户信息
        Customers customer = baseMapper.selectOne(Wrappers.lambdaQuery(Customers.class).eq(Customers::getPhoneNumber, telephone));
        //如果用户不存在，创建新用户
        if (Objects.isNull(customer)) {
            customer = new Customers();
            customer.setLoginAccount(telephone);  //手机号
            customer.setCustomerName(telephone);  //手机号
            customer.setPhoneNumber(telephone);  //手机号
            this.save(customer);
        }
        //不为空则登录成功
        return createTokenAndUserVo(request, customer);
    }

    @Override
    public Customers isLogged(String token) {
        //如果为空表示没有登录
        Assert.error(StringUtils.isEmpty(token), BusinessCode.USER_NOT_LOGGED);
        //判断Token是否有效
        boolean isValid = jwtUtil.validateToken(token);
        Assert.error(!isValid, BusinessCode.INVALID_TOKEN);
        //获取用户的ID
        Long userId = Long.valueOf(jwtUtil.getValue(token, "userId"));
        //调用业务层查询用户是否存在
        Customers customer = baseMapper.selectOne(Wrappers.lambdaQuery(Customers.class)
                                        .eq(Customers::getId, userId));
        Assert.error(customer == null, BusinessCode.USER_NOT_EXIST);
        return customer;
    }

    @Override
    public void logout(String token, HttpServletResponse response) {
        //通过token得到用户id
        String userId = jwtUtil.getValue(token, "userId");
        //删除redis中的token
        redisTemplate.delete(RedisConst.USER_TOKEN_PREFIX + ":" + userId);
    }

    /**
     * 生成Token，并且封装UserVo对象
     */
    private Customers createTokenAndUserVo(HttpServletRequest request, Customers customers) {
        //1.生成Token
        HashMap<String, Object> data = new HashMap<>();
        data.put("loginAccount", customers.getLoginAccount());
        data.put("userId", customers.getId());
        //为了安全，判断IP地址是否相同
        data.put("ip", jwtUtil.getRequestIP(request));
        String token = jwtUtil.createToken(data);
        customers.setToken(token);
        String key = RedisConst.USER_TOKEN_PREFIX + ":" + customers.getId();
        redisTemplate.opsForValue().set(key, token, Duration.ofDays(1));

        return customers;
    }

    @Autowired
    private CustomersMapper customersMapper;

    public Customers getCustomerByPhone(String phoneNumber) {
        // 使用 MyBatis-Plus 的查询方法
        return customersMapper.selectOne(
                new QueryWrapper<Customers>()
                        .eq("phone_number", phoneNumber)
        );
    }
}




